/**
 * Copyright 2010 Butin Kirill <kiryaka@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.flexupload
{
	import flash.net.FileReferenceList;
	
	import mx.utils.StringUtil;
	
	import org.flexupload.event.FlexuploadEventDispatcher;
	import org.flexupload.manager.FileManager;
	import org.flexupload.manager.UploadManager;
	import org.flexupload.remote.FlexuploadService;
	import org.flexupload.status.MessageHelper;
	import org.flexupload.status.UploadStatus;
	import org.flexupload.strategy.DevStrategy;
	
	public class Flexupload extends FlexuploadEventDispatcher 
	{
		public static const SPEED_UPDATE:String = "speed_update";
		private static var _instance:Flexupload = new Flexupload();
		private var fileManager:FileManager = new FileManager();
		private var uploadStatus:UploadStatus = new UploadStatus();
		private var uploadMessageHelper:MessageHelper = new MessageHelper();
		private var strategy:DevStrategy;
		private var uploadManager:UploadManager = new UploadManager();
	
		public function Flexupload(){
			checkInstance();
			super();
			strategy = new DevStrategy();
			strategy.setUploadStatus(uploadStatus);
			uploadManager.setUploadStatus(uploadStatus);
			uploadManager.setFileManager(fileManager);
			uploadManager.setStrategy(strategy);
		}
		public function getStrategy():DevStrategy{
			return strategy;
		}
		private function checkInstance():void{
			if (_instance != null)
				throw new Error("Singleton can only be accessed through Singleton.instance");
		}
		public static function getInstance():Flexupload
		{
			if (_instance == null) _instance = new Flexupload();
			return _instance;
		}
		public static function destroyInstance():void{
			_instance = null;
		}
		
		
		public function addFileList(fileList:FileReferenceList):void{
			fileManager.addFileList(fileList);
		}	
		public function start():void{
			strategy.start();
			uploadManager.start();
			uploadStatus.start();
			getUploadStatus().startUpload();
		}
		
		public function finish():void{
			getUploadStatus().finishUpload();
			uploadStatus.finish();
			uploadManager.finish();
		}		
		public function getUploadStatus():UploadStatus{
			return uploadStatus;
		}		
		public function GetCommonProgressLabel():String{
			var res:String = StringUtil.substitute("{0}/{1}, Avg: {2}, Cur: {3}",
				uploadMessageHelper.humanReadableSize(uploadStatus.getBytesTransfered()),
				uploadMessageHelper.humanReadableSize(uploadStatus.getTotalBytes()),
				uploadMessageHelper.humanReadableSpeed(uploadStatus.getAverageSpeed()),
				uploadMessageHelper.humanReadableSpeed(uploadStatus.getCurrentSpeed()));
			return res;
		}
		
		/**
		 * Set server side destination (source for Zend Amf), or set server simulation mode for debug (serverURL = local).
		 *  
		 * @param serverURL - URL to remote service or "local" to enable server simulation mode
		 * @param serverDestination - remote server destination
		 * @param serverSource - in case of PHP Zend Amf we need to write service name here
		 * 
		 */
		public function setServerUrl(serverURL:String, serverDestination:String, serverSource:String = null):void{
			strategy.setServerUrl(serverURL, serverDestination, serverSource);
		}
		
		public function getControlService():FlexuploadService{
			return strategy.getControlService();
		}
		
		public function removeFile(name:String):void{
			fileManager.removeFile(name);
		}
	}	
}